package com.tandashi.springbootstudy01.config;

import com.tandashi.springbootstudy01.security.shiro.StudyAuthorizingRealm;
import com.tandashi.springbootstudy01.service.user.WeChatUserService;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.filter.mgt.DefaultFilter;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import javax.servlet.Filter;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    Realm realm(WeChatUserService weChatUserService){
        return new StudyAuthorizingRealm(weChatUserService);
    }

    /**
     *  Add this bean declaration is to make Unit Test work.
     *  TpbbPricipalUtils need 'was' to load DefaultWebSessionManager.
     *  If no such declaration, ServletContainerSessionManager will be loaded instead.
     * @return
     */
    @Bean
    ServletContainerSessionManager sessionManager(){
        return new ServletContainerSessionManager();
    }

    @Profile({"dev","local","special"})
    @Bean
    DefaultWebSessionManager defaultWebSessionManager(){
        return new DefaultWebSessionManager();
    }

    @Bean
    ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition filterChainDefinition = new DefaultShiroFilterChainDefinition();
        //swagger
        filterChainDefinition.addPathDefinition("/common/**", DefaultFilter.anon.name());
        filterChainDefinition.addPathDefinition("/trigger/**", DefaultFilter.anon.name());
        filterChainDefinition.addPathDefinition("/vers2/**", "swaggerFilter");
        filterChainDefinition.addPathDefinition("/swagger-ui.html", DefaultFilter.anon.name());
        filterChainDefinition.addPathDefinition("/swagger-resources/**", DefaultFilter.anon.name());
        filterChainDefinition.addPathDefinition("/webjars/**", DefaultFilter.anon.name());

        //login
        filterChainDefinition.addPathDefinition("/login/**", DefaultFilter.anon.name());
        //it is authenticated by {@link com.tandashi.springbootstudy01.config.StudyAuthFilter}.
        filterChainDefinition.addPathDefinition("/testB/**", "studyAuthFilter");
        //see com.tandashi.springbootstudy01.controller.HelloController
        filterChainDefinition.addPathDefinition("/noauth/**", DefaultFilter.anon.name());

        filterChainDefinition.addPathDefinition("/testA/**", DefaultFilter.anon.name());

        filterChainDefinition.addPathDefinition("/opening/**", DefaultFilter.anon.name());

        //this line must be the last one.
        filterChainDefinition.addPathDefinition("/**", "loginFilter");

        return filterChainDefinition;

    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
                                                         ShiroFilterChainDefinition shiroFilterChainDefinition){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
        filterMap.put("loginFilter",new AppUserFilter());
        filterMap.put("swaggerFilter",new AppUserSwaggerFilter());
        filterMap.put("studyAuthFilter",new StudyAuthFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
        return shiroFilterFactoryBean;
    }
}
